home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / graphics / display / mpega / src / user_interface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-20  |  11.1 KB  |  358 lines

  1. /*------------------------------------------------------------------------------
  2.  
  3.     File    :    user_interface.c
  4.  
  5.     Author  :    Stéphane TAVENARD
  6.  
  7.     $VER:   user_interface.c  1.1  (27/07/1995)
  8.  
  9.     (C) Copyright 1995-1995 Stéphane TAVENARD
  10.     All Rights Reserved
  11.  
  12.     #Rev|   Date   |              Comment
  13.     ----|----------|--------------------------------------------------------
  14.     0    |05/06/1995| Initial revision                      ST
  15.     1    |23/06/1995| First release (aminet)                               ST
  16.     2    |27/07/1995| Added mixing frequency                  ST
  17.  
  18.     ------------------------------------------------------------------------
  19.  
  20.     User (Text) interface for MPEG audio decoding
  21.  
  22. ------------------------------------------------------------------------------*/
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <time.h>
  28. #include "mpega_decode_asm.h"
  29. #include "mpega_decode.h"
  30. #include "user_interface.h"
  31.  
  32. #define NULL_CHAR '\0'
  33.  
  34. static char *Version = "$VER:MPEGA (Fast MPEG audio decoder) V1.1 (C)Stéphane TAVENARD";
  35. static char *mode_names[4] = { "stereo", "j-stereo", "dual-ch", "single-ch" };
  36. static char *layer_names[3] = { "I", "II", "III" };
  37. static char *programName;
  38. static int   display_header_only = 0;
  39. static clock_t time_to_decode;
  40.  
  41. static void write_header_info( frame_params *fr_ps, FILE *s )
  42. {
  43.    layer *info = fr_ps->header;
  44.  
  45.    fprintf( s, "HDR:  s=FFF, id=%X, l=%X, ep=%X, br=%X, sf=%X, pd=%X, ",
  46.         info->version, info->lay, !info->error_protection,
  47.         info->bitrate_index, info->sampling_frequency, info->padding );
  48.    fprintf( s, "pr=%X, m=%X, js=%X, c=%X, o=%X, e=%X\n",
  49.         info->extension, info->mode, info->mode_ext,
  50.         info->copyright, info->original, info->emphasis );
  51.    fprintf( s, "layer=%s, tot bitrate=%d, sfrq=%d, mode=%s, ",
  52.         layer_names[ info->lay-1 ], fr_ps->bitstream_rate,
  53.         fr_ps->bitstream_freq, mode_names[ info->mode ] );
  54.    fprintf( s, "sblim=%d, jsbd=%d, ch=%d\n",
  55.         fr_ps->sblimit, fr_ps->jsbound, fr_ps->stereo );
  56.    fflush( s );
  57. }
  58.  
  59. static void usage( void )
  60. /*-----------------------
  61.    Display MPEG Audio decoder usage
  62. */
  63. {
  64.    FILE *s;
  65.  
  66.    s = stderr;
  67.    fprintf( s, "%s\n", &Version[ 5 ] );
  68.    fprintf( s, "Adapted from 'musicout' of MPEG/audio software simulation group\n" );
  69.    fprintf( s, "Fast integer version by Stéphane TAVENARD ["__DATE__"]\n" );
  70.    fprintf( s, "MPEG decoding has been optimzed (68020+ assembler rewritten) for layers I & II\n" );
  71.    fprintf( s, "Can play real time now (if you have enough CPU power) !\n" );
  72.    fprintf( s, "email: tavenard@xiii.univ-angers.fr\n\n" );
  73.    fprintf( s, "usage: %s -> queries for all arguments, or\n", programName);
  74.    fprintf( s, "       %s [-A][-d div][-q qual][-e sh][-h][-m][-p][-f 0|1][-x freq] inputBS [outPCM]\n", programName);
  75.    fprintf( s, "where\n");
  76.    fprintf( s, " -A       write an AIFF output PCM sound file\n");
  77.    fprintf( s, " -d div   output frequency divide (1, 2 or 4)\n");
  78.    fprintf( s, " -q qual  output quality (0=worst 2=best)\n");
  79.    fprintf( s, " -e sh    8 bits output with sh bits right shifted (8 usually)\n");
  80.    fprintf( s, " -h       display header only\n" );
  81.    fprintf( s, " -m       mono output (=left voice)\n" );
  82.    fprintf( s, " -p       play audio\n" );
  83.    fprintf( s, " -f 0|1   audio filter off/on\n" );
  84.    fprintf( s, " -x freq  mixing frequency\n" );
  85.    fprintf( s, " inputBS  input bit stream of encoded audio\n");
  86.    fprintf( s, " outPCM   output PCM sound file (dflt inName+%s)\n", DFLT_OPEXT );
  87.    fprintf( s, "\nEnjoy fast MPEG :-) \n" );
  88. }
  89.  
  90. void USIN_get_parameters( int argc, char **argv, frame_params *fr_ps )
  91. /*--------------------------------------------------------------------
  92.    Get MPEG Audio decode parameters
  93. */
  94. {
  95.    static char encoded_file_name[ MAX_NAME_SIZE ];
  96.    static char decoded_file_name[ MAX_NAME_SIZE ];
  97.    char t[ 50 ];
  98.    int    quality_set = 0;
  99.    int    audio_filter_set = 0;
  100.    int    value;
  101.  
  102.    programName = argv[ 0 ];
  103.    fr_ps->mixing_frequency = 0;
  104.    if( argc == 1 ) {        /* no command line args -> interact */
  105.       do {
  106.      usage();
  107.      printf( "Enter encoded file name <required>: " );
  108.      gets( encoded_file_name );
  109.      if( encoded_file_name[ 0 ] == NULL_CHAR )
  110.         printf( "Encoded file name is required. \n" );
  111.       } while( encoded_file_name[ 0 ] == NULL_CHAR );
  112.       printf( ">>> Encoded file name is: %s \n", encoded_file_name );
  113.  
  114.       printf( "Do you want audio play ? (y/<n>) : " );
  115.       gets( t );
  116.       if( (*t == 'y') || (*t == 'Y') ) {
  117.      fr_ps->play = 1;
  118.       }
  119.       if( !fr_ps->play ) {
  120.      printf( "Enter MPEG decoded file name <%s%s>: ", encoded_file_name,
  121.           DFLT_OPEXT );
  122.      gets( decoded_file_name );
  123.  
  124.      if( decoded_file_name[ 0 ] == NULL_CHAR ) {
  125.         strcat( strcpy( decoded_file_name, encoded_file_name ), DFLT_OPEXT );
  126.      }
  127.      printf( ">>> MPEG decoded file name is: %s \n", decoded_file_name );
  128.       }
  129.  
  130.       printf( "Frequency division output (<1>/2/4) : " );
  131.       gets( t );
  132.       fr_ps->freq_div = atoi( t );
  133.       if( (fr_ps->freq_div != 1) && (fr_ps->freq_div != 2) &&
  134.       (fr_ps->freq_div != 4) ) fr_ps->freq_div = 1;
  135.  
  136.       printf( "Ouput quality (0/1/<2>) : " );
  137.       gets( t );
  138.       if( !*t ) fr_ps->quality = 2;
  139.       else fr_ps->quality = atoi( t );
  140.       if( fr_ps->quality < 0 ) fr_ps->quality = 0;
  141.       else if( fr_ps->quality > 2 ) fr_ps->quality = 2;
  142.  
  143.       printf( "Do you want mono output ? (y/<n>) : ");
  144.       gets( t );
  145.       if( (*t == 'y') || (*t == 'Y') ) fr_ps->mono_forced = TRUE;
  146.  
  147.       printf( "Do you want 8 bits output ? (y/<n>) : ");
  148.       gets( t );
  149.       if( (*t == 'y') || (*t == 'Y') ) {
  150.      fr_ps->output_8bits = 8;
  151.       }
  152.       if( !fr_ps->play ) {
  153.      printf( "Do you wish to write an AIFF compatible sound file ? (y/<n>) : " );
  154.      gets( t );
  155.      if( (*t == 'y') || (*t == 'Y') ) {
  156.         fr_ps->out_file_type = MPEGA_FILETYPE_AIFF;
  157.         printf( ">>> An AIFF compatible sound file will be written\n" );
  158.      }
  159.      else {
  160.         fr_ps->out_file_type = MPEGA_FILETYPE_RAW;
  161.         printf( ">>> A non-headered PCM sound file will be written\n" );
  162.      }
  163.       }
  164.       printf( "Do you wish to exit (last chance before decoding) ? (y/<n>) : " );
  165.       gets( t );
  166.       if( (*t == 'y') || (*t == 'Y') ) exit( 0 );
  167.    }
  168.    else {     /* interpret CL Args */
  169.       int i=0, err=0;
  170.  
  171.       encoded_file_name[ 0 ] = '\0';
  172.       decoded_file_name[ 0 ] = '\0';
  173.       while( (++i<argc) && (err == 0) ) {
  174.      char c, *token, *arg, *nextArg;
  175.      int  argUsed;
  176.  
  177.      token = argv[ i ];
  178.      if( *token++ == '-' ) {
  179.         if( (i+1) < argc ) nextArg = argv[ i+1 ];
  180.         else           nextArg = "";
  181.         argUsed = 0;
  182.         while( c = *token++ ) {
  183.            if( *token ) arg = token;
  184.            else        arg = nextArg;
  185.            switch( c ) {
  186.           case 'A':  fr_ps->out_file_type = MPEGA_FILETYPE_AIFF;
  187.                   break;
  188.           case 'd':  value = atoi( arg ); argUsed = 1;
  189.                   switch( value ) {
  190.                  case 1:
  191.                     if( !quality_set ) fr_ps->quality = 2;
  192.                     if( !audio_filter_set ) fr_ps->audio_filter = 0;
  193.                     fr_ps->freq_div = value;
  194.                     break;
  195.                  case 2:
  196.                     if( !quality_set ) fr_ps->quality = 1;
  197.                     if( !audio_filter_set ) fr_ps->audio_filter = 0;
  198.                     fr_ps->freq_div = value;
  199.                     break;
  200.                  case 4:
  201.                     if( !quality_set ) fr_ps->quality = 0;
  202.                     if( !audio_filter_set ) fr_ps->audio_filter = 1;
  203.                     fr_ps->freq_div = value;
  204.                     break;
  205.                  default:
  206.                     fprintf( stderr, "%s: invalid option value -%c %ld\n",
  207.                          programName, c, value );
  208.                     err = 1;
  209.                  break;
  210.                   }
  211.                   break;
  212.            case 'q':  value = atoi( arg ); argUsed = 1;
  213.                   switch( value ) {
  214.                  case 0:
  215.                  case 1:
  216.                  case 2:
  217.                     fr_ps->quality = value;
  218.                     quality_set = TRUE;
  219.                     break;
  220.                  default:
  221.                     fprintf( stderr, "%s: invalid option value -%c %ld\n",
  222.                          programName, c, value );
  223.                     err = 1;
  224.                  break;
  225.                   }
  226.                   break;
  227.            case 'f':  value = atoi( arg ); argUsed = 1;
  228.                   switch( value ) {
  229.                  case 0:
  230.                  case 1:
  231.                     fr_ps->audio_filter = value;
  232.                     audio_filter_set = TRUE;
  233.                     break;
  234.                  default:
  235.                     fprintf( stderr, "%s: invalid option value -%c %ld\n",
  236.                          programName, c, value );
  237.                     err = 1;
  238.                  break;
  239.                   }
  240.                   break;
  241.            case 'e':  fr_ps->output_8bits = atoi( arg ); argUsed = 1;
  242.                   if( fr_ps->output_8bits < 0 ) fr_ps->output_8bits = 0;
  243.                   else if( fr_ps->output_8bits > 8 ) fr_ps->output_8bits = 8;
  244.                   break;
  245.            case 'm':  fr_ps->mono_forced = TRUE;
  246.                   break;
  247.            case 'p':  fr_ps->play = TRUE;
  248.                   break;
  249.            case 'h':  display_header_only = TRUE;
  250.                   break;
  251.            case 'x':  fr_ps->mixing_frequency = atoi( arg ); argUsed = 1;
  252.                   break;
  253.            default:   fprintf( stderr,"%s: unrecognized option %c\n",
  254.                        programName, c );
  255.               err = 1; break;
  256.         }
  257.         if( argUsed ) {
  258.            if( arg == token ) token = ""; /* no more from token */
  259.            else           ++i; /* skip arg we used */
  260.            arg = ""; argUsed = 0;
  261.         }
  262.          }
  263.       }
  264.       else {
  265.          if( encoded_file_name[ 0 ] == '\0' )
  266.         strcpy( encoded_file_name, argv[ i ] );
  267.          else
  268.         if( decoded_file_name[ 0 ] == '\0' )
  269.            strcpy( decoded_file_name, argv[ i ] );
  270.         else {
  271.            fprintf( stderr,
  272.                 "%s: excess arg %s\n", programName, argv[i] );
  273.            err = 1;
  274.         }
  275.       }
  276.        }
  277.  
  278.        if( err || (encoded_file_name[ 0 ] == '\0') ) {
  279.       usage();
  280.       exit( 0 );
  281.        }
  282.        if( decoded_file_name[ 0 ] == '\0' ) {
  283.       strcpy( decoded_file_name, encoded_file_name );
  284.       strcat( decoded_file_name, DFLT_OPEXT );
  285.        }
  286.  
  287.     }
  288.  
  289.    /* report results of dialog / command line */
  290.    if( !display_header_only ) {
  291.       if( !fr_ps->play ) {
  292.      printf( "Input file = '%s'  output file = '%s'\n",
  293.         encoded_file_name, decoded_file_name );
  294.       }
  295.       else {
  296.      printf( "Input file = '%s'  output -> audio\n", encoded_file_name );
  297.       }
  298.       if( fr_ps->out_file_type == MPEGA_FILETYPE_AIFF ) {
  299.      printf("Output file written in AIFF format\n");
  300.       }
  301.       if( fr_ps->freq_div != 1 ) {
  302.      printf( "Output frequency/%ld.\n", fr_ps->freq_div );
  303.       }
  304.       if( fr_ps->mono_forced ) {
  305.      printf( "Mono ouput forced.\n" );
  306.       }
  307.       if( fr_ps->output_8bits ) {
  308.      printf( "8 bits output selected.\n" );
  309.       }
  310.       printf( "Output quality %ld\n", fr_ps->quality );
  311.     }
  312.  
  313.     fr_ps->bitstream_name = encoded_file_name;
  314.     if( display_header_only ) {
  315.       fr_ps->out_file_name = NULL;
  316.     }
  317.     else {
  318.       fr_ps->out_file_name = decoded_file_name;
  319.     }
  320. }
  321.  
  322. void USIN_display_info( frame_params *fr_ps )
  323. /*-----------------------------------------
  324.    display current frame info
  325.    -> exit if display_header_only is set
  326. */
  327. {
  328.    write_header_info( fr_ps, stderr );
  329.    if( display_header_only ) exit( 0 );
  330.    time_to_decode = clock();
  331. }
  332.  
  333. void USIN_display_frame_number( frame_params *fr_ps )
  334. /*---------------------------------------------------
  335.    display current frame number
  336.    -> exit if display_header_only is set
  337. */
  338. {
  339.    fprintf( stderr, "{%4lu}\r", fr_ps->frame_count ); fflush( stderr );
  340. }
  341.  
  342. void USIN_epilog( frame_params *fr_ps )
  343. /*-------------------------------------
  344.    Write epilog info
  345. */
  346. {
  347.    time_to_decode = clock() - time_to_decode;
  348.  
  349.    if( fr_ps->out_sample_freq ) {
  350.       printf( "Stream time=%.2lf sec\n",
  351.           (double)(fr_ps->out_sample_length)
  352.           / (double)(fr_ps->out_sample_freq) );
  353.    }
  354.  
  355.    printf( "Total time used to decode the stream was %.2lf secs.\n",
  356.        (double)time_to_decode / CLK_TCK);
  357. }
  358.